package com.hikobe8.learnmedia

import android.annotation.SuppressLint
import android.content.pm.PackageManager
import android.media.AudioFormat
import android.media.AudioRecord
import android.media.MediaRecorder
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.TextView
import android.widget.Toast
import com.hikobe8.learnmedia.databinding.ActivityMainBinding
import java.io.File
import java.io.FileOutputStream

class MainActivity : AppCompatActivity() {

    val TAG = "hikobe8"
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        //request record audio permission
        if (checkSelfPermission(android.Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
            val REQUEST_RECORD_AUDIO_PERMISSION = 0
            requestPermissions(arrayOf(android.Manifest.permission.RECORD_AUDIO), REQUEST_RECORD_AUDIO_PERMISSION)
        }
        if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            val REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION = 1
            requestPermissions(arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE), REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION)
        }
    }

    /**
     * A native method that is implemented by the 'learnmedia' native library,
     * which is packaged with this application.
     */
    external fun pcmToMp3JNI(pcmPath: String, mp3Path: String,
                             sampleRate: Int, channel: Int, bitRate: Int): Int

    companion object {
        // Used to load the 'learnmedia' library on application startup.
        init {
            System.loadLibrary("learnmedia")
        }
    }

    private lateinit var audioRecord: AudioRecord
    private var pcmFilePath: String = ""
    private var buffersize = 1024
    private var isRecord = false

    /**
     * 调用Native代码完成PCM文件转成MP3
     */
    fun pcm2mp3(view: View) {
        val pcmPath = getPCMFile().absolutePath
        val mp3Path = getMP3File().absolutePath
        Log.d(TAG, "pcmPath: $pcmPath, mp3Path: $mp3Path")
        val sampleRate = 44100
        val channel = 2
        val bitRate = 64000
        val ret = pcmToMp3JNI(pcmPath, mp3Path, sampleRate, channel, bitRate)
        Toast.makeText(this, "$ret", Toast.LENGTH_SHORT).show()
    }

    /**
     * 开始录制PCM音频文件
     */
    @SuppressLint("MissingPermission")
    fun startRecordPcm(view: View) {
        val frequency = 44100
        val channelConfig = AudioFormat.CHANNEL_IN_STEREO
        val audioEncoding = AudioFormat.ENCODING_PCM_16BIT
        buffersize = AudioRecord.getMinBufferSize(frequency, channelConfig, audioEncoding)
        audioRecord = AudioRecord(
            MediaRecorder.AudioSource.MIC,
            frequency,
            channelConfig,
            audioEncoding,
            buffersize)
        pcmFilePath = getPCMFile().absolutePath
        isRecord = true
        RecordThread().start()
    }

    /**
     * 结束录制PCM音频文件
     */
    fun stopRecordPcm(view: View) {
        isRecord = false
    }

    private fun getPCMFile(): File {
        val root = getExternalFilesDir(null)
        val csvDir = File(root, "/audio/")
        if (!csvDir.exists()) {
            // 创建csv 目录
            csvDir.mkdir()
        }
        return File(csvDir, "sing.pcm")
    }

    private fun getMP3File(): File {
        val root = getExternalFilesDir(null)
        val csvDir = File(root, "/audio/")
        if (!csvDir.exists()) {
            // 创建csv 目录
            csvDir.mkdir()
        }
        return File(csvDir, "sing.mp3")
    }

    /**
     * 录制PCM音频线程
     */
    inner class RecordThread : Thread() {
        override fun run() {
            audioRecord.startRecording()
            var fos: FileOutputStream? = null
            try {
                Log.d(TAG, "pcm文件：$pcmFilePath")
                fos = FileOutputStream(pcmFilePath)
                val bytes = ByteArray(buffersize)
                while (isRecord) {
                    audioRecord.read(bytes, 0, bytes.size)
                    fos.write(bytes, 0, bytes.size)
                    fos.flush()
                }
                Log.d(TAG, "停止录制")
                audioRecord.stop()
                fos.flush()
            } catch (e: Exception) {
                Log.d(TAG, "exception: $e")
            } finally {
                if (fos != null) {
                    try {
                        fos.close()
                    } catch (e: Exception) {
                    }
                }
            }
        }
    }
}